package net.es.weathermap.metric;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;

import org.apache.log4j.Logger;


public class MetricCache {
    // Cache for 1 minutes
    private static Logger LOG = Logger.getLogger(MetricCache.class);
    private Long timeout = 15000L;
    private HashMap<String, CacheEntry> entries;

    public Long getTimeout() {
        return timeout;
    }

    public void setTimeout(Long timeout) {
        this.timeout = timeout;
    }

    public MetricCache() {
        LOG.info("initializing cache...");
        entries = new HashMap<String, CacheEntry>();
    }

    public HashMap<String, CacheEntry> getMetrics(List<String> identifiers) {
        Long now = System.currentTimeMillis();
        HashMap<String, CacheEntry> cached = new HashMap<String, CacheEntry>();
        for (String id : identifiers) {
            CacheEntry ce = entries.get(id);
            if (ce != null && ce.getTimestamp() > now - timeout) {
                cached.put(id, ce);
            }
        }
        return cached;
    }

    /**
     * return latest values no matter how old
     * @param identifiers
     * @return the values that correspond to the identifiers or 0.0
     */
    public HashMap<String, CacheEntry> getStale(List<String> identifiers) {

        HashMap<String, CacheEntry> results = new HashMap<String, CacheEntry>();
        for (String id : identifiers) {
            CacheEntry ce;
            ce = entries.get(id);
            if (ce != null) {
                results.put(id, ce);
            } else {
                ce = new CacheEntry();
                ce.setTimestamp(0L);
                HashMap<String, ArrayList<Double>> entry = new
                    HashMap<String, ArrayList<Double>>();
                ArrayList<Double> vals = new ArrayList<Double>();
                vals.add(0.0D);
                entry.put("in", vals);
                vals = new ArrayList<Double>();
                vals.add(0.0D);
                entry.put("out", vals);
                ce.setEntry(entry);
            }
        }
        return results;
    }

    public void cacheMetrics(HashMap<String, CacheEntry> newMetrics) {
        if (newMetrics == null) {
            return;
        }
        Long now = System.currentTimeMillis();
        Iterator<String> idIt = newMetrics.keySet().iterator();
        while (idIt.hasNext()) {
            String id = idIt.next();
            // LOG.debug("caching id: "+id);
            CacheEntry ce = new CacheEntry();
            ce.setTimestamp(now);
            ce.setEntry(newMetrics.get(id).getEntry());
            entries.put(id, ce);
        }
    }

    public void clear() {
        entries = new HashMap<String, CacheEntry>();
    }
}
